<template>
	<a-modal
		:visible="visible"
		width="1000px"
		title="转租"
		centered
		destroyOnClose
		:maskClosable="false"
		@cancel="cancel"
		:footer="null"
		:bodyStyle="{padding: 0}">
		<a-form
			ref="formRef"
			:model="modelRef"
			:rules="formRules"
			layout="horizontal"
			class="flex-container-nomal"
			:labelCol="{style: {width: '90px'}}"
			style="height: 70vh"
			@finish="submit">
			<div class="flex1 auto-y">
				<a-space :size="12" direction="vertical" style="width: 100%">
					<div class="d-module-title">
						<b>房间信息</b>
					</div>
					<a-form-item label="" name="houseAddress">
						<a-input v-model:value="modelRef.houseAddress" disabled placeholder="请输入房源地址" />
					</a-form-item>

					<div class="d-module-title">
						<b>退租情况</b>
					</div>
					<a-row :gutter="16" style="height: 35px">
						<a-col>
							<a-form-item label="退租日期" name="quiteDate" :rules="[{required: true, message: '请选择退租日期'}]">
								<a-date-picker
									style="width: 200px"
									v-model:value="modelRef.quiteDate"
									:value-format="DATE_FORMAT.DATE"
									:disabled-date="disabledDate"
									@change="incomeList()" />
							</a-form-item>
						</a-col>
						<a-col>
							<a-form-item label="退款账号" name="paymentNo">
								<a-input-group compact>
									<a-form-item-rest>
										<a-select
											v-model:value="modelRef.paymentType"
											:options="paymentAccountList"
											placeholder="请选择类型"
											style="width: 120px" />
									</a-form-item-rest>
									<a-input style="width: 200px" v-model:value="modelRef.paymentNo" placeholder="请输入账号" />
								</a-input-group>
							</a-form-item>
						</a-col>
						<a-col>
							<a-button type="primary" @click="visibles.delivery = true" style="width: 160px">
								<check-outlined v-if="JSON.stringify(delivery.info) != '{}'" />
								<plus-outlined v-else />
								添加退房交割单
							</a-button>
						</a-col>
					</a-row>
					<a-row :gutter="15" v-if="[1].includes(modelRef.paymentType)">
						<a-col>
							<a-form-item label="银行行号" name="bankNumber">
								<a-input style="width: 200px" v-model:value="modelRef.bankNumber" placeholder="请输入银行行号" />
							</a-form-item>
						</a-col>
						<a-col>
							<a-form-item label="开户银行" name="bankName">
								<a-input style="width: 320px" v-model:value="modelRef.bankName" placeholder="请输入开户银行" />
							</a-form-item>
						</a-col>
					</a-row>
					<div class="d-module-title">
						<b>退租明细</b>
					</div>
					<vxe-grid v-bind="gridOptions" :data="tableData" align="center">
						<template #feeDirection="{row}">
							<svg-icon
								:icon-class="`finance-${row.feeDirection == 1 ? 'in' : 'out'}`"
								style="width: 22px; height: 14px; margin-right: 6px" />
							<span :class="(row.feeDirection == 1 ? 'processing' : 'error') + '-color'">
								{{ row.feeDirection == 1 ? '收' : '支' }}
							</span>
						</template>
						<template #feeSubject="{row}">
							<a-select
								v-model:value="row.feeSubjectId"
								:class="{error: !row.feeSubjectId}"
								:disabled="row.disabled"
								:options="row.isNew?useFeeSubject:feeSubject"
								show-search
								option-filter-prop="name"
								:field-names="{label: 'name', value: 'id', options: 'metaList'}"
								placeholder="请选择费用科目"
								style="width: 100%; text-align: left" />
						</template>
						<template #amount="{row}">
							<a-input-number
								v-model:value="row.notOccurredMoney"
								:class="{error: row.notOccurredMoney === null || row.notOccurredMoney < 0}"
								:min="0"
								:precision="2"
								placeholder="请输入金额"
								style="width: 100%" />
						</template>
						<template #cycle="{row}">
							<a-range-picker
								:class="{error: !row.timeInfo.length}"
								style="width: 100%"
								v-model:value="row.timeInfo"
								:value-format="DATE_FORMAT.DATE" />
						</template>
						<template #action="{row, rowIndex}">
							<a-button type="link" size="small" danger @click="tableData.splice(rowIndex, 1)">删除</a-button>
						</template>
						<template #bottom>
							<vxe-toolbar perfect>
								<template #buttons>
									<span>费用总计：{{ totalMoney.toLocaleString() }}元</span>
								</template>
								<template #tools>
									<a-space v-if="!(props.bizId && [1, '1'].includes(props.enterpriseSignType))">
										<a class="processing" @click="addTogether(1)">
											<plus-square-outlined />
											添加收款项
										</a>
										<a class="error" @click="addTogether(2)">
											<minus-square-outlined />
											添加付款项
										</a>
									</a-space>
								</template>
							</vxe-toolbar>
						</template>
					</vxe-grid>

					<div class="d-module-title">
						<b>备注</b>
					</div>
					<a-form-item label="" name="quiteComment">
						<a-textarea v-model:value="modelRef.quiteComment" placeholder="请输入备注" :rows="4" show-count :maxlength="200" />
					</a-form-item>
				</a-space>
			</div>
			<div class="a-modal-dialog-footer">
				<a-space :size="12">
					<a-button @click="cancel">取消</a-button>
					<a-button type="primary" html-type="submit">确定</a-button>
				</a-space>
			</div>
		</a-form>
	</a-modal>
	<lease-off-settlement
		v-model:visible="visibles.delivery"
		:houseId="modelRef.houseId"
		:is-resubmit="isResubmit"
		:id="props.contractId"
		@success="getDelivery" />
	<!-- 包租合同 -->
	<signing-dialog v-model:visible="visibles.contract" :contract="contractData" :signing-type="'renter'" @success="renterSignSuccess" />
	<!-- <renter-sign-dialog v-model:visible="visibles.contract" :contract="contractData" @success="renterSignSuccess" /> -->
</template>
<script setup lang="ts">
	import {computed, reactive, ref, watch} from 'vue'
	import {getCommission, cabcelBreakAbnormalList, getRenterContractDetail, tenantBreakNormalList} from '@/api/contract'
	import {paymentAccountList} from '@/utils'
	import {MinusSquareOutlined, PlusOutlined, PlusSquareOutlined, CheckOutlined} from '@ant-design/icons-vue'
	import dayjs, {Dayjs} from 'dayjs'
	import LeaseOffSettlement from './lease-off-settlements.vue'
	import RenterSignDialog from '@/components/contract/tenant/renter-sign-dialog.vue'
	import {RenterContract} from '@/interface/contract'
	import settingApi from 'yuxin-base/src/api/setting-api'
	import {DIC_LABEL_MAP} from 'yuxin-base/src/constant'
	import DATE_FORMAT, {nowDate} from 'yuxin-base/src/utils/date'
	import billApi from '@/api/bill-api'
	import GenerateBill from '@/components/finance/generate-bill/index.vue'
	import {VxeGridProps, VxeTablePropTypes} from 'vxe-table'
	import {isLockinEnv} from 'yuxin-base/src/utils'
	import {message, Modal} from 'ant-design-vue'
	import SigningDialog from '@/components/contract/signing/signing-dialog.vue'
	import XEUtils from 'xe-utils'

	const props = defineProps({
		visible: {
			type: Boolean,
			required: true
		},
		contractId: {
			type: String
		},
		tenantData: {
			type: Object
		},
		isResubmit: {
			type: Boolean,
			required: false
		}
	})
	const modelRef = reactive({
		// 只作展示用的字段
		houseAddress: '',
		houseId: '',
		quiteDate: '',
		quiteComment: '',
		normal: 0,
		paymentType: 1,
		paymentNo: '',
		bankNumber: null,
		bankName: null
	})
	const contractId = ref()
	const minxinData = ref<RenterContract>({})

	/**
	 * 合同开始日期
	 */
	const contractBeginDate = ref()

	const formRules = {}

	const feeSubject = ref<any>([])
	const useFeeSubject = ref<any>([])

	const beginDate = ref()
	const endDate = ref()
	const disabledDate = (current: Dayjs) => {
		if (minxinData.value.resubmit) {
			return current.isBefore(beginDate.value, 'day') || current.isAfter(endDate.value, 'day')
		} else {
			// 退租日期不能小于合同开始日期，并且不能大于当前日期
			return current.isBefore(beginDate.value, 'day') || current.isAfter(dayjs(), 'day')
		}
	}
	const isResubmit = ref(false)
	const getData = () => {
		// 获取费用科目列表
		// 82308字典修改
		settingApi.getDicListByLabel(DIC_LABEL_MAP.FEESUBJECT, {isUse: null}).then(({data}) => (feeSubject.value = data))

		// 82308字典修改
		settingApi.getDicListByLabel(DIC_LABEL_MAP.FEESUBJECT, {isUse: 1}).then(({data}) => (useFeeSubject.value = data))

		// 获取租客详情
		getRenterContractDetail(props.contractId).then(({data}) => {
			minxinData.value = data
			contractId.value = data.id
			beginDate.value = data.beginTime
			modelRef.houseId = data.houseId
			modelRef.houseAddress = data.house.address

			let quiteDate: string
			if (props.tenantData && props.tenantData.quiteDate) {
				quiteDate = props.tenantData.quiteDate
			} else {
				if (dayjs().isBefore(data.beginTime, 'day')) {
					quiteDate = dayjs(data.beginTime).format(DATE_FORMAT.DATE)
				} else {
					quiteDate = nowDate()
				}
			}
			modelRef.quiteDate = quiteDate
			contractBeginDate.value = quiteDate

			// 如果该合同审批被驳回，重新提交转租操作，计算退租账单需要取contractPid
			isResubmit.value = false
			if (data.contractPid && [2, 4].includes(data.approvalStatus)) {
				isResubmit.value = true
				contractId.value = data.contractPid
				minxinData.value.resubmit = true
				// 退租日期不能大于上次提交的合同开始日期
				modelRef.quiteDate = endDate.value = dayjs(data.beginTime).subtract(1, 'day').format(DATE_FORMAT.DATE)

				getRenterContractDetail(contractId.value).then(({data}) => {
					beginDate.value = data.beginTime
					let billInfos = (data.billInfos || []).filter(o => o.num == 999) || [],
						bills = billInfos.length ? (billInfos[0]?.bills || []).filter(k => k.billType == 3) : [],
						finances = bills.length ? bills[0].finances : []
					billProcessing(finances)
				})
			}
			if (!isResubmit.value) {
				incomeList()
			}
		})
	}
	const incomeList = async (data: any = []) => {
		const params = {
			contractId: props.contractId,
			quiteDate: modelRef.quiteDate,
			meterReadRecordDtos: data,
			signType: 3 // 转租3 换房4
		}
		const res: any = await (modelRef.normal ? tenantBreakNormalList(params) : cabcelBreakAbnormalList(params))
		if (res.data.length) {
			billProcessing(res.data)
		}
	}
	const billProcessing = data => {
		data.forEach((item: any) => {
			item.disabled = true
			item.timeInfo = [item.beginDate, item.endDate]
			// 表单校验
			item.checkFeeSubjectId = true
			item.checkAmount = true
			item.checkTimeInfo = true
			if (!item.notOccurredMoney) {
				item.notOccurredMoney = item.amount
			}
		})
		tableData.value = data
		billListInfo()
		//转租手续费后端返，不需要前端加
		// if (!isResubmit.value) {
		// 	getCommissionCount()
		// }
	}
	const billList = async (data: any = []) => {
		data.forEach((item: any) => {
			item.disabled = true
			item.timeInfo = [item.beginDate, item.endDate]
			// 表单校验
			item.checkFeeSubjectId = true
			item.checkAmount = true
			item.checkTimeInfo = true
			let index = tableData.value.findIndex(o => o.id === item.id)
			if (index === -1) {
				tableData.value.push(item)
			} else {
				tableData.value[index] = {...item}
			}
		})
	}

	const totalMoney = computed(() => {
		let total = 0
		for (let item of tableData.value) {
			if (item.feeDirection === 1) {
				total += item.notOccurredMoney * 1
			} else {
				total -= item.notOccurredMoney * 1
			}
		}
		return total.toFixed(2)
	})

	// table ---------------------------------------------------------------------------------------------------------

	const gridOptions = reactive<VxeGridProps>({
		size: 'small',
		maxHeight: 400,
		rowConfig: {
			isHover: true,
			isCurrent: true
		},
		columns: [
			{
				title: '收支类型',
				field: 'feeDirection',
				width: 100,
				align: 'center',
				slots: {
					default: 'feeDirection'
				}
			},
			{
				title: '费用科目',
				field: 'feeSubjectId',
				minWidth: 200,
				align: 'center',
				slots: {
					default: 'feeSubject'
				}
			},
			{
				title: '金额(元)',
				field: 'amount',
				minWidth: 150,
				align: 'center',
				slots: {
					default: 'amount'
				}
			},
			{
				title: '账单周期',
				field: 'cycle',
				align: 'center',
				minWidth: 300,
				slots: {
					default: 'cycle'
				}
			},
			{
				title: '操作',
				align: 'center',
				width: 100,
				slots: {
					default: 'action'
				}
			}
		]
	})

	const tableData = ref<any>([])

	const visibles = reactive({
		contract: false,
		delivery: false,
		generateBill: false
	})

	const addTogether = (type: number | string) => {
		let obj = {
			amount: null, // 收支金额
			timeInfo: [],
			beginDate: '',
			costType: 0, // 费用类型
			endDate: '',
			feeDirection: type, // 费用方向【1收入2支出】
			feeSubjectId: null, // 费用科目id【字典】
			feeSubjectName: '', // 费用科目名称
			// 表单校验
			checkFeeSubjectId: true,
			checkAmount: true,
			checkTimeInfo: true,
			notOccurredMoney: null,
			isNew: true
		}
		tableData.value.push(obj)
	}
	const canceled = ref(true)
	watch(
		() => props.visible,
		(newVal: boolean) => {
			if (newVal && canceled.value && !props.isResubmit) {
				emit('update:visible', false)
				billApi.unclearedDeposit(props.contractId as string).then(({data = []}) => {
					if (data.length > 0) {
						message.error('原合同押金未结清，不能进行转租操作')
					} else {
						getData()
						canceled.value = false
						emit('update:visible', true)
					}
				})
			} else if (newVal && props.isResubmit) {
				getData()
				canceled.value = false
				emit('update:visible', true)
			}
		}
	)

	/** 换房手续费手续费 根据签约类型换房 signType = 4 转租 signType = 3 转租  */
	const getCommissionCount = () => {
		const from = {
			contractId: props.contractId,
			signType: 3
		}
		getCommission(from).then(res => {
			if (res.data !== null && res.data !== 0) {
				console.log('---', res.data)
				const price = res.data
				const metaList = feeSubject.value.find(item => item.label === 'FEESUBJECT@PROCEDURE')?.metaList
				const feeSubjectId = metaList.find(item => item.tag === 'SUBLEASE_PROCEDURE_FEE')?.id
				let obj = {
					amount: price, // 收支金额
					timeInfo: [nowDate(), nowDate()],
					beginDate: '',
					costType: 0, // 费用类型
					endDate: '',
					feeDirection: 1, // 费用方向【1收入2支出】
					feeSubjectId, // 费用科目id【字典】
					feeSubjectName: '', // 费用科目名称
					// 表单校验
					checkFeeSubjectId: true,
					checkAmount: true,
					checkTimeInfo: true,
					notOccurredMoney: price,
					disabled: true
				}
				tableData.value.push(obj)
			}
		})
	}

	const emit = defineEmits(['update:visible', 'success'])
	const cancel = () => {
		emit('update:visible', false)
		resetForm()
	}

	const delivery = reactive<any>({
		info: {}
	})
	const getDelivery = (data: any) => {
		delivery.info = data
		// 设备费用存在 刷新账单
		if (delivery.info?.meterReadRecordDtos && delivery.info.meterReadRecordDtos.length) {
			Modal.warning({
				title: '提示',
				content: '账单已更新，还请重新核对账单明细!'
			})
			incomeList(delivery.info.meterReadRecordDtos)
		} else {
			billListInfo()
		}
	}
	const billListInfo = () => {
		if (delivery.info?.earlyData && delivery.info.earlyData.length) {
			billList(delivery.info.earlyData)
		}
		// 能源预警
		if (delivery.info?.energyDictArr && delivery.info.energyDictArr.length) {
			billList(delivery.info.energyDictArr)
		}
	}
	const submit = async () => {
		// isBindEnergyDevice 是否绑定能耗设备 0.是 1.否
		let checkFee = false
		for (let item of tableData.value) {
			item.checkFeeSubjectId = !item.feeSubjectId ? false : true
			if (!item.feeSubjectId) {
				checkFee = true
			}
			item.checkAmount = !(item.notOccurredMoney * 1 >= 0) ? false : true
			if (item.notOccurredMoney === null || !(item.notOccurredMoney * 1 >= 0)) {
				checkFee = true
			}
			if (item.timeInfo.length == 0) {
				item.checkTimeInfo = false
				checkFee = true
			} else {
				item.beginDate = item.timeInfo[0]
				item.endDate = item.timeInfo[1]
				item.checkTimeInfo = true
			}
			// 总金额=未发生金额+已发生金额
			item.amount = item.notOccurredMoney + (item.occurredMoney || 0)
		}
		// isBindEnergyDevice 是否绑定能耗设备 0.是 1.否
		if (minxinData.value.isBindEnergyDevice === 0 && JSON.stringify(delivery.info) === '{}') {
			if (!isLockinEnv()) return message.error('请在交割单输入能耗读数')
		}
		if (checkFee) {
			return
		}

		contractData.value = returnData()
		console.log('🚀 ~ file: turn-rent-dialog.vue:493 ~ submit ~ contractData.value:', contractData.value)
		// 82308字典修改
		if (await isDisabledF()) return
		visibles.contract = true
	}

	// 合同签约数据
	const contractData = ref<RenterContract>({})
	const returnData = (): RenterContract => {
		let params: any = {}
		if (props.tenantData) {
			// 转租申请id
			params.applyId = props.tenantData.applyId
			params.renterInfo = {
				name: props.tenantData.subleaseName,
				phone: props.tenantData.subleasePhone,
				certificationType: Number(props.tenantData.subleaseCardType),
				identityCard: props.tenantData.subleaseCardNo
			}
		}

		// 转租日期不能早于合同开始日期
		if (dayjs(beginDate.value).isAfter(minxinData.value.beginTime, 'day')) {
			minxinData.value.beginTime = beginDate.value
		}

		// 如果合同已经开始（上一份的合同开始日期小于当前日期） 转租开始日期＋1
		if (contractBeginDate.value <= nowDate()) {
			minxinData.value.beginTime = dayjs(modelRef.quiteDate).add(1, 'day').format(DATE_FORMAT.DATE)
		}

		console.log('minxinData.value.beginTime====', minxinData.value.beginTime)

		// 组装老的退房交割单
		let oldDelivery = getOldDelivery()

		if (minxinData.value.resubmit) {
			return {
				...params,
				...minxinData.value,
				delivery: delivery.info,
				oldDelivery,
				quiteDate: modelRef.quiteDate,
				quiteComment: modelRef.quiteComment,
				oldContractBillInfos: tableData.value,
				endTime: minxinData.value.endTime
			}
		}

		return {
			...params,
			otherExpenses: [],
			oldContractBillInfos: tableData.value,
			contractPid: props.contractId,
			oldContractId: props.contractId,
			quiteDate: modelRef.quiteDate,
			quiteComment: modelRef.quiteComment,
			houseAddress: modelRef.houseAddress,
			houseId: minxinData.value.houseId,
			housePid: minxinData.value.housePid,
			beginTime: minxinData.value.beginTime,
			endTime: minxinData.value.endTime,
			signDeptId: minxinData.value.signDeptId,
			signEmpId: minxinData.value.signEmpId,
			maintainerId: minxinData.value.maintainerId,
			signType: 3,
			delivery: delivery.info,
			oldDelivery,
			// 企业框架相关字段 start
			contractType: minxinData.value.contractType,
			enterPriseId: minxinData.value.enterPriseId
			// 企业框架相关字段 end
		}
	}

	const renterSignSuccess = () => {
		emit('success')
		cancel()
	}

	// 重置表单
	const formRef = ref<any>()
	const resetForm = () => {
		modelRef.paymentType = 1
		tableData.value = []
		minxinData.value = {}
		canceled.value = true
		formRef.value.resetFields()
	}

	const getOldDelivery = () => {
		// 过滤字段 deviceType,deviceId,amount or lastRead=》read
		// 深拷贝一下 防止污染
		let newDelivery = JSON.parse(JSON.stringify(delivery.info))
		// 根据付费类型 不同的数组
		// let type = newDelivery.billGenerateMethod
		// if (type === 2 || type === 3) {
		// 	meters = newDelivery[type === 2 ? 'meterReadRecordDtos' : 'energyDictArr'].map((e: any) => {
		// 		return {
		// 			deviceType: e.deviceType,
		// 			deviceId: e.deviceId,
		// 			read: type === 2 ? e.amount : e.lastRead
		// 		}
		// 	})
		// 	delete newDelivery['meterReadRecordDtos']
		// 	delete newDelivery['energyDictArr']
		// }
		let meterReadRecordDtos = []
		if (newDelivery && newDelivery.constructor === Object && newDelivery.hasOwnProperty('meterReadRecordDtos')) {
			meterReadRecordDtos =
				(newDelivery.meterReadRecordDtos || []).map((e: any) => {
					return {
						deviceType: e.deviceType,
						deviceId: e.deviceId,
						read: e.amount
					}
				}) || []
			delete newDelivery['meterReadRecordDtos']
		}
		let energyDictArr = []
		if (newDelivery && newDelivery.constructor === Object && newDelivery.hasOwnProperty('energyDictArr')) {
			energyDictArr =
				(newDelivery.energyDictArr || []).map((e: any) => {
					return {
						deviceType: e.deviceType,
						deviceId: e.deviceId,
						read: e.lastRead
					}
				}) || []
			delete newDelivery['energyDictArr']
		}
		let meters = [...meterReadRecordDtos, ...energyDictArr]
		return {
			deliveryType: '2',
			compactType: '1',
			houseId: modelRef.houseId,
			compactId: props.contractId,
			...newDelivery,
			meters
		}
	}

	/* 判断选择的字典是否被禁用 */
	// / 82308字典修改
	const isDisabledF = async () => {
		let temp = false
		let typesList: any = []
		let list: any = []
		let dataList: any = XEUtils.clone(tableData.value, true)
		typesList = await settingApi.getDicListByLabel(DIC_LABEL_MAP['FEESUBJECT'], {isUse: 1})
		typesList.data.forEach((e: any) => {
			list.push(...e.metaList)
		})
		list.forEach((e: any) => {
			dataList.forEach((o: any) => {
				if (e.id === o.feeSubjectId) {
					o.active = true
				}
			})
		})
		if (!dataList?.every((e: any) => e?.active == true)) {
			temp = true
			return message.error('选项已禁用，请选择其他选项！')
		}
		return temp
	}
</script>

<style lang="less" scoped>
	:deep(.vxe-table--footer-wrapper.body--wrapper) {
		overflow: hidden;
	}
</style>
